/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package coda.util;

import coda.Config;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamReader;
import org.json.JSONArray;
import org.json.JSONObject;

class HTTPRequest {

    private String urlString;
    private Map<String, String> params = new LinkedHashMap<String, String>();

    public HTTPRequest (String urlString) {
        this.urlString = urlString;
    }

    public void addParameter(String name, String value) {
        String param = ((params.size() == 0) ? "?" : "&") + name;
        params.put(param, value);
    }

    public String getResult() throws MalformedURLException, IOException {
        StringBuilder buf = new StringBuilder(urlString);

        for (Iterator iter = params.entrySet().iterator(); iter.hasNext();) {
            Map.Entry tuple = (Entry) iter.next();
            buf.append(tuple.getKey());
            buf.append("=");
            buf.append(tuple.getValue());
        }
        URL url = new URL(buf.toString());
        BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
        StringBuilder response = new StringBuilder();
        String s;
        while ((s = reader.readLine()) != null) {
            response.append(s);
        }
        reader.close();

        return response.toString();
    }

}

/**
 *
 * @author pan
 */
public class Media {
    
    private final static String coverDir = Config.getInstance().getProperty("cover_directory", PathUtil.join(PathUtil.HOME, ".local", "share", "coda", "covers"));
    private final static String lyricDir = Config.getInstance().getProperty("lyric_directory", PathUtil.join(PathUtil.HOME, ".local", "share", "coda", "lyrics"));
    private final static ImageIcon cover = new ImageIcon(Media.class.getResource("/resources/media.png"));

    // Image related

    private static String getImageFileName(String artist, String album) {
        return artist.toLowerCase() + " - " + album.toLowerCase() + ".jpg";
    }

    public static List<ImageIcon> fetchCovers(String artist, String album) {
        List<ImageIcon> list = new ArrayList<ImageIcon>();

        HTTPRequest request = new HTTPRequest("http://ajax.googleapis.com/ajax/services/search/images");
        try {
            String query = URLEncoder.encode((artist + "+" + album).replaceAll(" ", "+"), "UTF-8");
            request.addParameter("v", "1.0");
            request.addParameter("q", query);

            String result = request.getResult();
            if (result != null && !result.isEmpty()) {
                JSONObject obj = new JSONObject(result);
                JSONObject responseData = obj.getJSONObject("responseData");
                JSONArray results = responseData.getJSONArray("results");
                for (int i = 0; i < results.length(); i++) {
                    JSONObject r = results.getJSONObject(i);
                    String ref = r.getString("url");
                    try {
                        Image g = ImageIO.read(new URL(ref)).getScaledInstance(100, 100, Image.SCALE_SMOOTH);
                        list.add(new ImageIcon(g));
                    } catch (Exception ex) {
                        System.out.println(ex.getMessage());
                    }
                }
            }
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }

        return list;
    }

    public static ImageIcon getCover(String artist, String album) {
        ImageIcon icon = cover;

        if (artist != null && album != null) {
            File f = new File(coverDir, getImageFileName(artist, album));
            if (f.exists()) {
                try {
                    Image image = ImageIO.read(f).getScaledInstance(100, 100, Image.SCALE_SMOOTH);
                    icon = new ImageIcon(image);
                } catch (Exception e) {
                    System.err.println(e.getMessage());
                }
            }
        }

        return icon;
    }

    public static void setCover(String artist, String album, ImageIcon icon) {
        Image image = icon.getImage();
        RenderedImage rendered;

        if (image instanceof RenderedImage) {
            rendered = (RenderedImage) image;
        } else {
            BufferedImage buffered = new BufferedImage(icon.getIconWidth(), icon.getIconHeight(), BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics = buffered.createGraphics();
            graphics.drawImage(image, 0, 0, null);
            graphics.dispose();
            rendered = buffered;
        }

        File f = new File(coverDir, getImageFileName(artist, album));
        try {
            ImageIO.write(rendered, "JPEG", f);
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }

    // Lyrics related

    private static String getLyricsFileName(String artist, String title) {
        return artist.toLowerCase() + " - " + title.toLowerCase() + ".txt";
    }

    private static String toUTF(String s) {
        try {
            return new String(s.getBytes("ISO8859-1"), "UTF-8");
        } catch (Exception e) {
            System.err.println(e.getMessage());
            return s;
        }
    }

    private static String toISO(String s) {
        try {
            s = s.replace("ё", "е");
            return new String(s.getBytes("UTF-8"), "ISO8859-1");
        } catch (Exception e) {
            System.err.println(e.getMessage());
            return s;
        }
    }

    private static String parseXHTML(URL url) {
        StringBuilder text = new StringBuilder();
        try {
            InputStream in = url.openStream();
            XMLInputFactory factory = XMLInputFactory.newInstance();
            XMLStreamReader parser = factory.createXMLStreamReader(in);
            System.out.println("parsing xhtml...");
            boolean read = false;
            while(parser.hasNext()) {
                int event = parser.next();
                switch (event) {
                    case XMLStreamConstants.START_ELEMENT:
                        if (parser.getLocalName().equals("div")) {
                            for (int i=0; i < parser.getAttributeCount(); i++) {
                                String name = parser.getAttributeLocalName(i);
                                if (name.equals("class")) {
                                    String value = parser.getAttributeValue(i);
                                    if (value.equals("lyricbox")) {
                                        read = true;
                                    }
                                }
                            }
                        }
                        break;
                    case XMLStreamConstants.CHARACTERS:
                        if (read) {
                            String s = parser.getText();
                            text.append(s);
                            text.append("\n");
                        }
                        break;
                    case XMLStreamConstants.END_ELEMENT:
                        if (parser.getLocalName().equals("div")) {
                            read = false;
                        }
                        break;
                }
            }
            parser.close();
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
        return text.toString();
    }

    public static String fetchLyrics(String artist, String title) {

        String lyrics = null;

        try {
            com.chartlyrics.api.Apiv1 service = new com.chartlyrics.api.Apiv1();
            com.chartlyrics.api.Apiv1Soap port = service.getApiv1Soap12();
            com.chartlyrics.api.GetLyricResult result = port.searchLyricDirect(artist, title);
            lyrics = result.getLyric();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return lyrics;
    }

    public static String getLyrics(String artist, String title) {
        String lyrics = null;

        File f = new File(lyricDir, getLyricsFileName(artist, title));
            System.out.println(f.getAbsolutePath());
        if (f.exists()) {
            try {
                lyrics = new Scanner(f).useDelimiter("\\Z").next();
            } catch (Exception e) {
                System.err.println(e.getMessage());
            }
        }

        return lyrics;
    }

    public static void setLyrics(String artist, String title, String lyrics) {
        File f = new File(lyricDir, getLyricsFileName(artist, title));
        try {
            FileWriter writer = new FileWriter(f);
            writer.write(lyrics);
            writer.close();
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }

}
